package cn.lic.tool.poi.excel;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.Row;

import com.alibaba.fastjson.JSONObject;
import cn.lic.tool.poi.excel.function.FunctionParser;
import cn.lic.tool.poi.excel.function.IFunction;
import cn.lic.tool.poi.excel.function.Range;
import cn.lic.tool.poi.excel.function.IValue.Type;

public class ExcelTemplateParser {
	JSONObject params = null;
	HSSFWorkbook book = null;
	
	public ExcelTemplateParser(JSONObject params, File template) throws Exception {
		this.params = params;
		book = new HSSFWorkbook(new FileInputStream(template));
		book.forEach((sheet)-> this.parseSheet((HSSFSheet)sheet));
//		HSSFSheet sheet = book.getSheetAt(0);
//		parseSheet(sheet);
	}
	
	protected void parseSheet(HSSFSheet sheet) {
		for (int rowIndex = 0; rowIndex <= sheet.getLastRowNum(); rowIndex++) {
			Row tplRow = sheet.getRow(rowIndex);
			for (int cellIndex = 0; tplRow != null && cellIndex <= tplRow.getLastCellNum(); cellIndex++) {
				Cell ctplCell = tplRow.getCell(cellIndex);
				// 忽略空单元格和非变量单元格
				if (ctplCell == null || ctplCell.getCellType() != CellType.STRING) {
					continue; 
				}
				String express = ctplCell.getStringCellValue();
				if (express == null || express.trim().length() < 4) {
					continue;
				}
				
				/* 解析单元格内只有一个函数或一个变量的情况 */ 
				IFunction fun =  FunctionParser.getFunction(express);
				if (fun != null) {
					Range range = fun.execute(params, ctplCell);
					if (range != null) {
						rowIndex = range.getEndRowIndex();
						cellIndex = range.getEndCellIndex();
					}
					continue;
				}

				/* 解析普通文本中包含的模板变量 */
				StringBuffer sb = new StringBuffer();
				Pattern pattern = Pattern.compile("\\$\\{[^${}]+\\}");
				Matcher m = pattern.matcher(express);
				while(m.find()) {
					String group = m.group();
					IFunction fun1 = Objects.requireNonNull(FunctionParser.getFunction(group), String.format("无法解析表达式: %1s， 函数不存在: %2s", express, group));
					String rs = fun1.execute(params).castValue(Type.STRING, "");
					m.appendReplacement(sb, rs);
				}
				// 如果是常规字符串且没有变量，则不做赋值操作
				if (sb.length() > 0) {
					m.appendTail(sb);
					ParserUtils.setCellValue(ctplCell, sb);
				}
			}
		}
	}
	
	public void write(OutputStream out) throws IOException {
		book.write(out);
	}
	
	public void write(File file) throws IOException {
		
//		Iterator<Cell> cells = tplSheet.getRow(1).cellIterator();
//		int i = 0;
//		while (cells.hasNext()) {
//			cells.next();
//			sheet.setColumnWidth(i, tplSheet.getColumnWidth(i));
//			i++;
//		}
//		
//		tplSheet.getMergedRegions().stream().forEach( region -> {
//			sheet.addMergedRegion(region);
//		});
		
		try(OutputStream stream = new FileOutputStream(file)) {
			book.write(stream);
		} catch(IOException e) {
			throw e;
		}
	}
	
//	private int copyRow(Row srcRow, int destStartRow) {
//		HSSFRow newRow = sheet.createRow(destStartRow);
//	//	srcRow.setRowNum(destStartRow - 1);
//		CellCopyPolicy policy = new CellCopyPolicy().createBuilder().build();
//		// newRow.copyRowFrom(srcRow, policy);
//		copyRow(srcRow, sheet.createRow(destStartRow), policy);
//		return destStartRow + 1;
//	}
	
}
